package com.example.tenant.service.tenant;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.tenant.config.ExcelExportUtil;
import com.example.tenant.config.ExcelReaderUtil;
import com.example.tenant.config.FileConfig;
import com.example.tenant.entity.*;
import com.example.tenant.mapper.*;
import com.example.tenant.service.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.util.Arrays;
import java.util.List;

@Service
@RequiredArgsConstructor
public class TenantService {

    // 租户
    private static final List<String> TABLES_TO_EXPORT_LIST = Arrays.asList("sys_menu.xlsx", "sys_post.xlsx", "sys_password_policy.xlsx", "sys_dict.xlsx",
            "sys_dict_item.xlsx", "sys_public_param.xlsx", "sys_r_group.xlsx", "sys_message.xlsx", "sys_message_relation.xlsx",
            "sys_schedule.xlsx", "sys_social_details.xlsx", "sys_system_config.xlsx", "sys_audit_log.xlsx", "sys_file.xlsx",
            "sys_file_group.xlsx", "sys_dept.xlsx"
    );
    // 全部导出
    private static final List<String> TABLES_NOTENANT_QUERY_LIST = Arrays.asList("sys_route_conf.xlsx", "sys_area.xlsx", "sys_i18n.xlsx");
    private static final List<String> QUERY_TABLE_CHILDREN = Arrays.asList("sys_user.xlsx", "sys_role.xlsx", "sys_client.xlsx");
    private final ExcelReaderUtil excelReaderUtil;
    private final SysAreaService sysAreaService;
    private final SysAreaMapper sysAreaMapper;
    private final SysAuditLogService sysAuditLogService;
    private final SysAuditLogMapper sysAuditLogMapper;
    private final SysClientAdminMapper sysClientAdminMapper;
    private final SysDeptService sysDeptService;
    private final SysDeptMapper sysDeptMapper;
    private final SysDeptClientMapper sysDeptClientMapper;
    private final SysDictService sysDictService;
    private final SysDictMapper sysDictMapper;
    private final SysDictItemService sysDictItemService;
    private final SysDictItemMapper sysDictItemMapper;
    private final SysFileService sysFileService;
    private final SysFileMapper sysFileMapper;
    private final SysFileGroupService sysFileGroupService;
    private final SysFileGroupMapper sysFileGroupMapper;
    private final SysI18nService sysI18nService;
    private final SysI18nMapper sysI18nMapper;
    private final SysMenuService sysMenuService;
    private final SysMenuMapper sysMenuMapper;
    private final SysMessageService sysMessageService;
    private final SysMessageMapper sysMessageMapper;
    private final SysMessageRelationService sysMessageRelationService;
    private final SysMessageRelationMapper sysMessageRelationMapper;
    private final SysClientService sysClientService;
    private final SysClientMapper sysClientMapper;
    private final SysPasswordPolicyService sysPasswordPolicyService;
    private final SysPasswordPolicyMapper sysPasswordPolicyMapper;
    private final SysPostService sysPostService;
    private final SysPostMapper sysPostMapper;
    private final SysPublicParamService sysPublicParamService;
    private final SysPublicParamMapper sysPublicParamMapper;
    private final SysRGroupRoleMapper sysRGroupRoleMapper;
    private final SysRGroupUserMapper sysRGroupUserMapper;
    private final SysRoleService sysRoleService;
    private final SysRoleMapper sysRoleMapper;
    private final SysRoleGroupService sysRoleGroupService;
    private final SysRoleGroupMapper sysRoleGroupManager;
    private final SysRoleMenuMapper sysRoleMenuMapper;
    private final SysRoleRelateMapper sysRoleRelateMapper;
    private final SysRouteConfService sysRouteConfService;
    private final SysRouteConfMapper sysRouteConfMapper;
    private final SysScheduleService sysScheduleService;
    private final SysScheduleMapper sysScheduleMapper;
    private final SysSocialDetailsService sysSocialDetailsService;
    private final SysSocialDetailsMapper sysSocialDetailsMapper;
    private final SysSystemConfigService sysSystemConfigService;
    private final SysSystemConfigMapper sysSystemConfigMapper;
    private final SysTenantService sysTenantService;
    private final SysTenantMapper sysTenantMapper;
    private final SysUserService sysUserService;
    private final SysUserMapper sysUserMapper;
    private final SysUserClientMapper sysUserClientMapper;
    private final SysUserDeptMapper sysUserDeptMapper;
    private final SysUserPostMapper sysUserPostMapper;
    private final SysUserRoleMapper sysUserRoleMapper;

    @SneakyThrows
    @DS("secondary")
    @Transactional(rollbackFor = Exception.class)
    public void imp(String filePath) {
        File folder = new File(filePath);
        File[] listOfFiles = folder.listFiles((dir, name) -> name.endsWith(".xlsx"));
        if (listOfFiles != null) {
            for (File file : listOfFiles) {
                try (FileInputStream fis = new FileInputStream(file)) {
                    excelReader(file.getName(), fis);
                }
            }
        }
    }

    private void excelReader(String fileName, InputStream inputStream) {
        switch (fileName) {
            case "sys_area.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysAreaEntity.class, sysAreaMapper);
                break;
            case "sys_audit_log.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysAuditLog.class, sysAuditLogMapper);
                break;
            case "sys_client_admin.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysClientAdmin.class, sysClientAdminMapper);
                break;
            case "sys_dept.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysDept.class, sysDeptMapper);
                break;
            case "sys_dept_client.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysDeptClient.class, sysDeptClientMapper);
                break;
            case "sys_dict.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysDict.class, sysDictMapper);
                break;
            case "sys_dict_item.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysDictItem.class, sysDictItemMapper);
                break;
            case "sys_file.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysFile.class, sysFileMapper);
                break;
            case "sys_file_group.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysFileGroup.class, sysFileGroupMapper);
                break;
            case "sys_i18n.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysI18nEntity.class, sysI18nMapper);
                break;
            case "sys_menu.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysMenu.class, sysMenuMapper);
                break;
            case "sys_message.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysMessageEntity.class, sysMessageMapper);
                break;
            case "sys_message_relation.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysMessageRelationEntity.class, sysMessageRelationMapper);
                break;
            case "sys_client.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysOauthClientDetails.class, sysClientMapper);
                break;
            case "sys_password_policy.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysPasswordPolicy.class, sysPasswordPolicyMapper);
                break;
            case "sys_post.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysPost.class, sysPostMapper);
                break;
            case "sys_public_param.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysPublicParam.class, sysPublicParamMapper);
                break;
            case "sys_r_group_role.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRGroupRole.class, sysRGroupRoleMapper);
                break;
            case "sys_r_group_user.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRGroupUser.class, sysRGroupUserMapper);
                break;
            case "sys_role.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRole.class, sysRoleMapper);
                break;
            case "sys_role_group.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRoleGroup.class, sysRoleGroupManager);
                break;
            case "sys_role_menu.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRoleMenu.class, sysRoleMenuMapper);
                break;
            case "sys_role_relate.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRoleRelate.class, sysRoleRelateMapper);
                break;
            case "sys_route_conf.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysRouteConf.class, sysRouteConfMapper);
                break;
            case "sys_schedule.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysScheduleEntity.class, sysScheduleMapper);
                break;
            case "sys_social_details.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysSocialDetails.class, sysSocialDetailsMapper);
                break;
            case "sys_system_config.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysSystemConfigEntity.class, sysSystemConfigMapper);
                break;
            case "sys_tenant.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysTenant.class, sysTenantMapper);
                break;
            case "sys_user.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysUser.class, sysUserMapper);
                break;
            case "sys_user_client.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysUserClient.class, sysUserClientMapper);
                break;
            case "sys_user_dept.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysUserDept.class, sysUserDeptMapper);
                break;
            case "sys_user_post.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysUserPost.class, sysUserPostMapper);
                break;
            case "sys_user_role.xlsx":
                excelReaderUtil.readExcelFile(inputStream, SysUserRole.class, sysUserRoleMapper);
                break;
            default:
                // 处理未知文件名的情况
                System.out.println("未知文件名: " + fileName);
                break;
        }
    }

    @SneakyThrows
    public void export(Long tenantId, String filePath) {
        File folder = new File(filePath);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        FileConfig[] filesToExport = {
                new FileConfig("sys_user.xlsx", SysUser.class, sysUserService),
                new FileConfig("sys_role.xlsx", SysRole.class, sysRoleService),
                new FileConfig("sys_menu.xlsx", SysMenu.class, sysMenuService),
                new FileConfig("sys_post.xlsx", SysPost.class, sysPostService),
                new FileConfig("sys_password_policy.xlsx", SysPasswordPolicy.class, sysPasswordPolicyService),
                new FileConfig("sys_dict.xlsx", SysDict.class, sysDictService),
                new FileConfig("sys_dict_item.xlsx", SysDictItem.class, sysDictItemService),
                new FileConfig("sys_public_param.xlsx", SysPublicParam.class, sysPublicParamService),
                new FileConfig("sys_r_group.xlsx", SysRoleGroup.class, sysRoleGroupService),
                new FileConfig("sys_message.xlsx", SysMessageEntity.class, sysMessageService),
                new FileConfig("sys_message_relation.xlsx", SysMessageRelationEntity.class, sysMessageRelationService),
                new FileConfig("sys_schedule.xlsx", SysScheduleEntity.class, sysScheduleService),
                new FileConfig("sys_social_details.xlsx", SysSocialDetails.class, sysSocialDetailsService),
                new FileConfig("sys_system_config.xlsx", SysSystemConfigEntity.class, sysSystemConfigService),
                new FileConfig("sys_audit_log.xlsx", SysAuditLog.class, sysAuditLogService),
                new FileConfig("sys_file.xlsx", SysFile.class, sysFileService),
                new FileConfig("sys_file_group.xlsx", SysFileGroup.class, sysFileGroupService),
                new FileConfig("sys_dept.xlsx", SysDept.class, sysDeptService),
                new FileConfig("sys_area.xlsx", SysAreaEntity.class, sysAreaService),
                new FileConfig("sys_route_conf.xlsx", SysRouteConf.class, sysRouteConfService),
                new FileConfig("sys_i18n.xlsx", SysI18nEntity.class, sysI18nService),
                new FileConfig("sys_client.xlsx", SysOauthClientDetails.class, sysClientService),
                new FileConfig("sys_tenant.xlsx", SysTenant.class, sysTenantService)
        };
        for (FileConfig fileConfig : filesToExport) {
            String fileName = fileConfig.getFileName();
            Class<T> entityClass = fileConfig.getEntityClass();
            IService<T> service = fileConfig.getService();

            // 生成文件路径
            String fullPath = filePath + File.separator + fileName;
            File excelFile = new File(fullPath);

            try (FileOutputStream fos = new FileOutputStream(excelFile)) {
                if (TABLES_TO_EXPORT_LIST.contains(fileName)) {
                    ExcelExportUtil.exportExcelToFile(service, tenantId, entityClass, fos);
                } else if (TABLES_NOTENANT_QUERY_LIST.contains(fileName)) {
                    ExcelExportUtil.exportExcelToFile(service, null, entityClass, fos);
                } else if (QUERY_TABLE_CHILDREN.contains(fileName)) {
                    switch (fileName) {
                        case "sys_user.xlsx":
                            sysUserService.export(tenantId, fos, filePath);
                            break;
                        case "sys_role.xlsx":
                            sysRoleService.export(tenantId, fos, filePath);
                            break;
                        case "sys_client.xlsx":
                            sysClientService.export(tenantId, fos, filePath);
                            break;
                        default:
                            break;
                    }

                } else {
                    sysTenantService.export(tenantId, fos);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//        // 租户相关
//        tenantExport(tenantId, zipOutputStream);
//
    }

    /*
     * 导出租户数据
     */
//    private void tenantExport(Long tenantId, ZipOutputStream zipOutputStream) {
//
//        sysUserService.export(tenantId, zipOutputStream);
//
//        sysRoleService.export(tenantId, zipOutputStream);
//
//        sysClientService.export(tenantId, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysDeptService, tenantId, "sys_dept.xlsx", SysDept.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysAuditLogService, tenantId, "sys_audit_log.xlsx", SysAuditLog.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysDictService, tenantId, "sys_dict.xlsx", SysDict.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysDictItemService, tenantId, "sys_dict_item.xlsx", SysDictItem.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysFileService, tenantId, "sys_file.xlsx", SysFile.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysFileGroupService, tenantId, "sys_file_group.xlsx", SysFileGroup.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysMenuService, tenantId, "sys_menu.xlsx", SysMenu.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysPostService, tenantId, "sys_post.xlsx", SysPost.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysPasswordPolicyService, tenantId, "sys_password_policy.xlsx", SysPasswordPolicy.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysPublicParamService, tenantId, "sys_public_param.xlsx", SysPublicParam.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysRoleGroupService, tenantId, "sys_role_group.xlsx", SysRoleGroup.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysMessageService, tenantId, "sys_message.xlsx", SysMessageEntity.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysMessageRelationService, tenantId, "sys_message_relation.xlsx", SysMessageRelationEntity.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysScheduleService, tenantId, "sys_schedule.xlsx", SysScheduleEntity.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysSocialDetailsService, tenantId, "sys_social_details.xlsx", SysSocialDetails.class, zipOutputStream);
//
//        ExcelExportUtil.exportExcelToFile(sysSystemConfigService, tenantId, "sys_system_config.xlsx", SysSystemConfigEntity.class, zipOutputStream);
//
//    }
}